from flask import Blueprint, current_app, jsonify, session, request, json
from app.utils.code import RET
from app.utils.common import login_required
from app.utils.util import md5
from app.models import AreaModel, HouseModel, OrderModel, DeviceModel, HouseImageModel
from app import db
import os
import datetime

api_house = Blueprint("api_house", __name__)

''' 获取房源列表 '''
@api_house.route("/houses", methods=["GET"])
def get_house_list():
    """获取房屋的列表信息（搜索页面）"""
    start_date = request.args.get("sd", "")  # 用户想要的起始时间
    end_date = request.args.get("ed", "")  # 用户想要的结束时间
    area_id = request.args.get("aid", "")  # 区域编号
    sort_key = request.args.get("sk", "new")  # 排序关键字
    page = request.args.get("p")  # 页数

    # 处理时间
    try:
        if start_date:
            start_date = datetime.datetime.strptime(start_date, "%Y-%m-%d")

        if end_date:
            end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d")

        if start_date and end_date:
            assert start_date <= end_date
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="日期参数有误")

    # 判断区域id
    if area_id:
        try:
            AreaModel.query.get(area_id)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.PARAMERR, errmsg="区域参数有误")

    # 处理页数
    try:
        page = int(page)
    except Exception as e:
        current_app.logger.error(e)
        page = 1

    # 过滤条件的参数列表容器
    filter_params = []

    filter_params.append(HouseModel.is_deleted == 0)

    # 填充过滤参数
    # 时间条件
    conflict_orders = None

    try:
        if start_date and end_date:
            # 查询冲突的订单
            conflict_orders = OrderModel.query.filter(OrderModel.begin_date <= end_date, OrderModel.end_date >= start_date).all()
        elif start_date:
            conflict_orders = OrderModel.query.filter(OrderModel.end_date >= start_date).all()
        elif end_date:
            conflict_orders = OrderModel.query.filter(OrderModel.begin_date <= end_date).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库异常")

    if conflict_orders:
        # 从订单中获取冲突的房屋id
        conflict_house_ids = [order.house_id for order in conflict_orders]

        # 如果冲突的房屋id不为空，向查询参数中添加条件
        if conflict_house_ids:
            filter_params.append(HouseModel.id.notin_(conflict_house_ids))

    # 区域条件
    if area_id:
        filter_params.append(HouseModel.area_id == area_id)

    # 查询数据库
    # 补充排序条件
    if sort_key == "booking":  # 入住最多
        house_query = HouseModel.query.filter(*filter_params).order_by(HouseModel.order_count.desc())
    elif sort_key == "price-inc":
        house_query = HouseModel.query.filter(*filter_params).order_by(HouseModel.price.asc())
    elif sort_key == "price-des":
        house_query = HouseModel.query.filter(*filter_params).order_by(HouseModel.price.desc())
    else:  # 新旧
        house_query = HouseModel.query.filter(*filter_params).order_by(HouseModel.create_time.desc())

    # 处理分页
    try:
        #当前页数          每页数据量                              自动的错误输出
        page_obj = house_query.paginate(page=page, per_page=15, error_out=False)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库异常")

    # 获取页面数据
    house_li = page_obj.items
    houses = []
    for house in house_li:
        houses.append(house.to_basic_json())

    # 获取总页数
    total_page = page_obj.pages

    resp_dict = dict(errno=RET.OK, errmsg="OK", data={"total_page": total_page, "houses": houses, "current_page": page})
    resp_json = json.dumps(resp_dict)

    return resp_json, 200, {"Content-Type": "application/json"}

''' 添加房源 '''
@api_house.route('/houses/add', methods=["POST"])
def add_house():
    json_dict = request.get_json()

    title = json_dict.get('title')
    price = json_dict.get('price')
    address = json_dict.get('address')
    room_count = json_dict.get('room_count')
    acreage = json_dict.get('acreage')
    unit = json_dict.get('unit')
    capacity = json_dict.get('capacity')
    beds = json_dict.get('beds')
    deposit = json_dict.get('deposit')
    min_days = json_dict.get('min_days')
    max_days = json_dict.get('max_days')
    area_id = json_dict.get('area_id')
    devices_id = json_dict.get('devices')

    # 判断参数是否完整
    if not all([title, price, address, room_count, acreage, unit, capacity, beds, deposit, min_days, area_id]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    try:
        house = HouseModel(title=title, price=price, address=address, room_count=room_count, acreage=acreage, unit=unit, capacity=capacity, beds=beds, deposit=deposit,max_days=max_days,min_days=min_days, area_id=area_id, user_id=session['user_id'])
        devices = DeviceModel.query.filter(DeviceModel.id.in_(devices_id)).all()
        house.devices = devices
        db.session.add(house)
        db.session.commit()
        return jsonify(errno=RET.OK, errmsg="添加成功", data={"house_id": house.id})
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="添加失败")

''' 添加房源图片 '''
@api_house.route("/houses/image", methods=["POST"])
def add_house_image():
    house_id = request.form.get('house_id', 0)
    files = request.files

    if "house_image" not in files:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    
    # 保存图片到服务器
    file = files.get("house_image")
    name, ext = file.filename.split(".")
    img = "/static/upload/" + md5(name) + "." + ext
    file.save(os.path.dirname(__file__) + "/.." + img)
    
    try:
        # 判断是否为第一张图片
        count = HouseImageModel.query.filter_by(house_id=house_id).count()
        if count == 0:
            # 是第一张图片，保存到房源表中
            house = HouseModel.query.filter_by(id=house_id).first()
            house.index_image = img
            db.session.add(house)

        house_image = HouseImageModel(house_id=house_id, image_url=img)
        db.session.add(house_image)
        db.session.commit()
        return jsonify(errno=RET.OK, errmsg="上传成功", data={"image_url": img})
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno = RET.DBERR, errmsg = "查询数据库异常")

''' 获取我发布的房源 '''
@api_house.route('/houses/my', methods=["GET"])
@login_required
def get_my_houses():
    try:
        houses = HouseModel.query.filter_by(user_id=session['user_id'], is_deleted=0).order_by(HouseModel.id.desc()).all()
        return jsonify(errno=RET.OK, data = [house.to_basic_json() for house in houses])
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据库异常")

''' 房源详细信息 '''
@api_house.route("/houses/<house_id>", methods=["GET"])
@login_required
def get_house_detail(house_id):
    if not house_id:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    try:
        house = HouseModel.query.filter_by(id=house_id, is_deleted=0).first()
    except Exception as e:
        return jsonify(errno=RET.DBERR, errmsg="查询数据库异常")
    
    if house is None:
        return jsonify(errno=RET.DATANOTEXIST, errmsg="房源不存在")

    return jsonify(errno=RET.OK, data={"user_id": session['user_id'], "house": house.to_full_json()})

@api_house.route("/houses/<house_id>/delete", methods=["DELETE"])
def delete_my_house(house_id):
    try:
        house = HouseModel.query.filter_by(id=house_id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.DBERR, errmsg = "查询数据库异常") 
    
    if not house:
        jsonify(errno=RET.DATANOTEXIST, errmsg="房源不存在")

    # 判断是否有在租的订单
    try:
        # 0 待接单，1 待支付，2 已支付，3 待评价，4 已完成，5 已取消，6 已拒单
        count = OrderModel.query.filter(OrderModel.id==house_id, OrderModel.status.notin_([4, 5, 6])).count()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.DBERR, errmsg = "查询数据库异常")
    
    if count:
        return jsonify(errno=RET.DATAEXIST, errmsg="房源有订单不能删除")
    
    try:
        house.is_deleted = 1
        db.session.add(house)
        db.session.commit()
        return jsonify(errno=RET.OK, errmsg="删除房源成功")
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno = RET.DBERR, errmsg = "修改数据库失败")


''' 首页轮播图 '''
@api_house.route("/banner", methods=["GET"])
def get_banner():
    try:
        # 查询数据库，返回房屋订单数目最多的5条数据
        houses = HouseModel.query.filter_by(is_deleted=0).order_by(HouseModel.order_count.desc()).limit(5)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据失败")

    if not houses:
        return jsonify(errno=RET.NODATA, errmsg="查询无数据")

    houses_list = []
    for house in houses:
        # 如果房屋未设置主图片，则跳过
        if not house.index_image:
            continue
        houses_list.append(house.to_basic_json())

    return jsonify(errno=RET.OK, errmsg="获取成功", data=houses_list)
